/**
 * @author lk
 * @date 2022/6/6 14:16
 */
package com.mmall.thread;

public class ProducerAndConsumer {

    public static void main(String[] args) {
        Repo repo = new Repo();
        Consumer consumer = new Consumer();
        Producer producer = new Producer();
        consumer.setRepo(repo);
        producer.setRepo(repo);

        Thread consumerThread = new Thread(consumer);
        consumerThread.setName("consumer");
        Thread producerThread = new Thread(producer);
        producerThread.setName("producer");
        consumerThread.start();
        producerThread.start();
    }
}

class Repo {
    public int storage = 0;
    public final int THREAD_HOLD = 50;
    void myWait() {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
    }
}



class Consumer implements Runnable {
    private Repo repo;

    @Override
    public void run() {
        while (true) {
            consume(10);
        }
    }

    public void consume(int amount) {
        synchronized (repo) {
            repo.notifyAll();
            while (repo.storage < repo.THREAD_HOLD) {
                repo.myWait();
            }
            repo.storage -= amount;
            System.out.println(Thread.currentThread().getName() + "后:" + repo.storage);
        }
    }

    public Repo getRepo() {
        return repo;
    }

    public void setRepo(Repo repo) {
        this.repo = repo;
    }
}

class Producer implements  Runnable {

    @Override
    public void run() {
        while (true) {
            produce(10);
        }
    }

    public void produce(int amount) {
        synchronized (repo) {
            repo.notifyAll();
            while (repo.storage > repo.THREAD_HOLD) {
                repo.myWait();
            }
            repo.storage += amount;
            System.out.println(Thread.currentThread().getName() + "后:" + repo.storage);
        }
    }

    public Repo getRepo() {
        return repo;
    }

    public void setRepo(Repo repo) {
        this.repo = repo;
    }

    private Repo repo;
}
